package com.heima.homeservicemanagementsystem.exception;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.NotRoleException;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.StrUtil;

import com.heima.homeservicemanagementsystem.module.Result;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.client.HttpClientErrorException;

import java.sql.SQLException;

/**
 * @Description
 * @Author susu
 * @Date 2024/11/25
 */
@Slf4j
@RestControllerAdvice
public class GlobalException {
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    @ExceptionHandler(value = NotLoginException.class)
    public Result<String> handle(NotLoginException e, HttpServletRequest request) {

        String tokeName = request.getHeader(StpUtil.getTokenName());
        if (StrUtil.isBlank(tokeName)) {
            return Result.error(401, "未递登录凭证", request.getRequestURI());
        }

        log.error("sa-token权限异常--->url:{}", request.getRequestURI(), e);
        Result<String> result = Result.error(401, e.getMessage(), request.getRequestURI());
        return result;
//        return new ResponseEntity<>(result, HttpStatus.UNAUTHORIZED).getBody();

    }

    @ExceptionHandler(StringIndexOutOfBoundsException.class)
    public ResponseEntity<Result> handleStringIndexOutOfBoundsException(StringIndexOutOfBoundsException e) {
        // 返回自定义的错误信息
        Result result = new Result(400, "Invalid string index", e.getMessage());
        return new ResponseEntity<>(result, HttpStatus.BAD_REQUEST);
    }


    @ExceptionHandler(value = NotPermissionException.class)
    public Result<String> handle(NotPermissionException e, HttpServletRequest request) {
        log.error("sa-token权限异常2--->url:{}", request.getRequestURI(), e);
        return Result.error(403, e.getMessage(), request.getRequestURI());
    }

    @ExceptionHandler(value = NotRoleException.class)
    public Result<String> handle(NotRoleException e, HttpServletRequest request) {
        log.error("sa-token权限异常3--->url:{}", request.getRequestURI(), e);
        return Result.error(403, e.getMessage(), request.getRequestURI());
    }

    @ExceptionHandler(value = SQLException.class)
    public Result<String> handle(SQLException e, HttpServletRequest request) {
        log.error("SQL异常--->url:{}", request.getRequestURI(), e);
        return Result.error(500, "SQL异常", e.getMessage());
    }

    // 处理 Unauthorized 异常
    @ExceptionHandler(value = HttpClientErrorException.Unauthorized.class)
    public Result<String> handleUnauthorizedException(HttpClientErrorException.Unauthorized e, HttpServletRequest request) {
        // 记录日志，包含请求的 URL 和异常信息
        log.error("Unauthorized access - URL: {}, Message: {}", request.getRequestURI(), e.getMessage());
        //可以写刷新access_token的相关信息

        // 返回统一的错误响应
        return Result.error(401, "Access token已经失效或者不存在", e.getMessage());
    }

    // 处理其他 HttpClientErrorException 异常（如 403 Forbidden 等）
    @ExceptionHandler(value = HttpClientErrorException.class)
    public Result<String> handleHttpClientErrorException(HttpClientErrorException e, HttpServletRequest request) {
        // 记录日志，包含请求的 URL 和异常信息
        log.error("HTTP client error - URL: {}, Status Code: {}, Message: {}", request.getRequestURI(), e.getStatusCode(), e.getMessage());

        // 返回统一的错误响应
        return Result.error(e.getStatusCode().value(), "HTTP client error", e.getMessage());
    }

    // 处理其他通用异常
    @ExceptionHandler(value = Exception.class)
    public Result<String> handleException(Exception e, HttpServletRequest request) {
        // 记录日志，包含请求的 URL 和异常信息
        log.error("Unexpected error - URL: {}, Message: {}", request.getRequestURI(), e.getMessage());

        // 返回统一的错误响应
        return Result.error(500, e.getMessage(), "Internal server error");
    }

}
